/*
 * Copyright (c) 2023-2023 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.redis.config;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.serializer.RedisSerializer;

/**
 * Redis 配置类
 *
 * @author zeng
 */
@EnableCaching
@AutoConfiguration
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisTemplateConfiguration {

  /**
   * redis 模板配置
   *
   * @param factory factory
   * @return 模板
   */
  @Bean
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setKeySerializer(RedisSerializer.string());
    redisTemplate.setHashKeySerializer(RedisSerializer.string());
    redisTemplate.setValueSerializer(RedisSerializer.java());
    redisTemplate.setHashValueSerializer(RedisSerializer.java());
    redisTemplate.setConnectionFactory(factory);
    return redisTemplate;
  }

  /**
   * 创建并返回一个用于操作Redis哈希的HashOperations实例。
   *
   * @param redisTemplate Redis模板，用于执行Redis操作。
   * @return HashOperations哈希操作接口，支持对Redis哈希的数据操作。
   */
  @Bean
  public HashOperations<String, String, Object> hashOperations(
      RedisTemplate<String, Object> redisTemplate) {
    return redisTemplate.opsForHash();
  }

  /**
   * 创建并返回一个用于操作Redis单值的ValueOperations实例。
   *
   * @param redisTemplate Redis模板，用于执行Redis操作。
   * @return 值操作接口，支持对Redis单个值的数据操作。
   */
  @Bean
  public ValueOperations<String, String> valueOperations(
      RedisTemplate<String, String> redisTemplate) {
    return redisTemplate.opsForValue();
  }

  /**
   * 创建并返回一个用于操作Redis列表的ListOperations实例。
   *
   * @param redisTemplate Redis模板，用于执行Redis操作。
   * @return 列表操作接口，支持对Redis列表的数据操作。
   */
  @Bean
  public ListOperations<String, Object> listOperations(
      RedisTemplate<String, Object> redisTemplate) {
    return redisTemplate.opsForList();
  }

  /**
   * 创建并返回一个用于操作Redis集合的SetOperations实例。
   *
   * @param redisTemplate Redis模板，用于执行Redis操作。
   * @return 集合操作接口，支持对Redis集合的数据操作。
   */
  @Bean
  public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
    return redisTemplate.opsForSet();
  }

  /**
   * 创建并返回一个用于操作Redis有序集合的ZSetOperations实例。
   *
   * @param redisTemplate Redis模板，用于执行Redis操作。
   * @return 有序集合操作接口，支持对Redis有序集合的数据操作。
   */
  @Bean
  public ZSetOperations<String, Object> zSetOperations(
      RedisTemplate<String, Object> redisTemplate) {
    return redisTemplate.opsForZSet();
  }
}
